<template>
  <div>
    <div class="dateInput" @click="isShowPicker=true">
      <input type="text" :value="dateValue" readonly />
    </div>
    <div class="datePicker" v-if="isShowPicker" @click.self="isShowPicker=false">
      <div class="date_wrapper">
        <!-- controller -->
        <div class="date_controller" v-if="showModuleType == 'day'">
          <div class="controller">
            <div @click="changeYear(0)" class="iconfont">&#xe63e;</div>
            <div @click="changeMonth(0)" class="iconfont">&#xe672;</div>
          </div>
          <div class="controller">
            <div @click="showModule('year')">{{currentDate.year}} 年</div>
            <div @click="showModule('month')">{{currentDate.month}} 月</div>
          </div>
          <div class="controller">
            <div @click="changeMonth(1)" class="iconfont">&#xe673;</div>
            <div @click="changeYear(1)" class="iconfont">&#xe63c;</div>
          </div>
        </div>
        <div class="date_controller" v-if="showModuleType == 'year'">
          <div class="controller iconfont" @click="changeYearScope(0)">&#xe63e;</div>
          <div class="controller">{{currentDate.year | yearFilter}}</div>
          <div class="controller iconfont" @click="changeYearScope(1)">&#xe63c;</div>
        </div>
        <div class="date_controller" v-if="showModuleType == 'month'">
          <div class="controller iconfont" @click="changeYear(0)">&#xe63e;</div>
          <div class="controller">{{currentDate.year}} 年</div>
          <div class="controller iconfont" @click="changeYear(1)">&#xe63c;</div>
        </div>
        <!-- date -->
        <div class="date_pick" v-if="showModuleType == 'day'">
          <div class="list">
            <div class="item" v-for="item in weekList" :key="item.id">{{item}}</div>
          </div>
          <div class="list">
            <div
              class="item"
              v-for="(item, index) in currentDay"
              :key="index"
              :class="{date_disabled: item.type != 'current',date_limit: item.limit}"
              @click="selectDay(item)"
            >
              <span
                :class="{date_active: item.type == 'current' && item.name == currentDate.day}"
              >{{item.name}}</span>
            </div>
          </div>
        </div>
        <!-- month -->
        <div class="month_pick" v-if="showModuleType == 'month'">
          <div
            class="item"
            v-for="item in currentMonth"
            :key="item.id"
            :class="{date_active: item.isSelect,date_limit:item.limit}"
            @click="selectMonth(item)"
          >{{item.name}}</div>
        </div>
        <!-- year -->
        <div class="year_pick" v-if="showModuleType == 'year'">
          <div
            class="item"
            v-for="item in currentYear"
            :key="item.id"
            :class="{date_active:item.isSelect,date_limit:item.limit}"
            @click="selectYear(item)"
          >{{item.name}}</div>
          <div class="item" style="height: 0" v-for="i in 2" :key="i.id"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
const _monthList = [
  "一",
  "二",
  "三",
  "四",
  "五",
  "六",
  "七",
  "八",
  "九",
  "十",
  "十一",
  "十二",
];
export default {
  props: {
    options: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      //展示时间
      dateValue: "",
      //是否显示日历
      isShowPicker: false,
      // 当前时间
      currentDate: {
        year: "2000",
        month: "4",
        day: "21",
      },
      // 展示模式
      showModuleType: "day",
      //周列表
      weekList: ["日", "一", "二", "三", "四", "五", "六"],
      // 日期列表
      currentDay: [],
      //年份列表
      currentYear: [],
      //月份列表
      currentMonth: [],
      // 年份范围
      yearScope: "",
    };
  },
  filters: {
    // 年份范围过滤
    yearFilter(year) {
      return `${parseInt(year / 10) + "0"} 年 - ${parseInt(year / 10) + "9"}年`;
    },
  },
  computed: {
    defaultOptions() {
      return {
        width: 500,
        height: 500,
        limit: ["2020-04-11", "2021-04-29"],
        ...this.options,
      };
    },
  },
  methods: {
    showModule(type) {
      this.showModuleType = type;
    },
    //切换年
    changeYear(i) {
      if (i == 1) {
        this.currentDate.year++;
      } else {
        this.currentDate.year--;
      }
      this._drawMonth();
      this._drawDay();
    },
    //切换月
    changeMonth(i) {
      if (i == 1) {
        if (this.currentDate.month == 12) {
          this.currentDate.month = 1;
          this.currentDate.year++;
        } else {
          this.currentDate.month++;
        }
      } else {
        if (this.currentDate.month == 1) {
          this.currentDate.month = 12;
          this.currentDate.year--;
        } else {
          this.currentDate.month--;
        }
      }
      this._drawMonth();
      this._drawDay();
    },
    //选择日期
    selectDay(item) {
      if (item.limit) return;
      if (item.type == "pre") {
        this.changeMonth(0);
      } else if (item.type == "next") {
        this.changeMonth(1);
      }
      this.currentDate.day = item.name;
      this.isShowPicker = false;
      this._renderInputVal();
    },
    //选择月份
    selectMonth(item) {
      if (item.limit) return;
      this.currentDate.month = item.value;
      this._drawMonth();
      this.showModuleType = "day";
    },
    //选择年份
    selectYear(item) {
      if (item.limit) return;
      this.currentDate.year = item.name;
      this.currentYear.map((item) => (item.isSelect = false));
      item.isSelect = true;
      this._drawMonth();
      this.showModuleType = "day";
    },
    //切换年份范围
    changeYearScope(i) {
      if (i == 0) {
        this.currentDate.year = (this.currentDate.year / 10 - 1) * 10;
      } else {
        this.currentDate.year = (this.currentDate.year / 10 + 1) * 10;
      }
      this._drawYear();
    },
    _drawDay() {
      //当前年份 1号星期几
      let date = new Date(
        this.currentDate.year,
        this.currentDate.month - 1,
        1
      ).getDay();
      //上月天数
      let preNumber = new Date(
        this.currentDate.year,
        this.currentDate.month - 1,
        0
      ).getDate();
      //当月天数
      let currentNumber = new Date(
        this.currentDate.year,
        this.currentDate.month,
        0
      ).getDate();
      //开始日期
      let startDate = preNumber - date;
      //结束日期
      let endDate = 42 - date - currentNumber;
      let preArr = [],
        curArr = [],
        nextArr = [];
      let preMonth =
        this.currentDate.month == 1 ? 12 : this.currentDate.month - 1;
      let nextMonth =
        this.currentDate.month == 12 ? 1 : this.currentDate.month + 1;
      let preYear =
        this.currentDate.month == 1
          ? this.currentDate.year - 1
          : this.currentDate.year;
      let nextYear =
        this.currentDate.month == 12
          ? this.currentDate.year + 1
          : this.currentDate.year;
      for (let i = startDate; i < preNumber; i++) {
        preArr.push({
          name: i,
          type: "pre",
          limit: this._limitDay(preYear, preMonth, i),
        });
      }
      for (let i = 1; i < currentNumber + 1; i++) {
        curArr.push({
          name: i,
          type: "current",
          limit: this._limitDay(
            this.currentDate.year,
            this.currentDate.month,
            i
          ),
        });
      }
      for (let i = 1; i < endDate + 1; i++) {
        nextArr.push({
          name: i,
          type: "next",
          limit: this._limitDay(nextYear, nextMonth, i),
        });
      }
      this.currentDay = [...preArr, ...curArr, ...nextArr];
    },
    _drawMonth() {
      this.currentMonth = [];
      _monthList.forEach((item, index) => {
        this.currentMonth.push({
          name: item + "月",
          value: index + 1,
          isSelect: !this._limitMonth(this.currentDate.year, index + 1) && this.currentDate.month == index + 1,
          limit: this._limitMonth(this.currentDate.year, index + 1),
        });
      });
    },
    _drawYear() {
      this.currentYear = [];
      let startYear = parseInt(this.currentDate.year / 10) + "";
      for (let i = 0; i < 10; i++) {
        this.currentYear.push({
          name: startYear + i,
          isSelect: !this._limitYear(startYear + i) && startYear + i == this.currentDate.year,
          limit: this._limitYear(startYear + i),
        });
      }
    },

    _limitDay(year, month, day) {
      let [startlimit, endlimit] = this.defaultOptions.limit;
      const [YS, MS, DS, YE, ME, DE, _day] = [
        parseInt(startlimit.slice(0, 4)),
        parseInt(startlimit.slice(5, 7)),
        parseInt(startlimit.slice(8, 10)),
        parseInt(endlimit.slice(0, 4)),
        parseInt(endlimit.slice(5, 7)),
        parseInt(endlimit.slice(8, 10)),
        parseInt(day),
      ];
      if (this._limitMonth(year, month)) {
        return true;
      } else {
        if (year == YS && month == MS) {
          return _day < DS;
        } else if (year == YE && month == ME) {
          return _day > DE;
        } else {
          return false;
        }
      }
    },
    _limitMonth(year, month) {
      const [startlimit, endlimit] = this.defaultOptions.limit;
      const [YS, MS, YE, ME, _month] = [
        parseInt(startlimit.slice(0, 4)),
        parseInt(startlimit.slice(5, 7)),
        parseInt(endlimit.slice(0, 4)),
        parseInt(endlimit.slice(5, 7)),
        parseInt(month),
      ];
      if (this._limitYear(year)) {
        return true;
      } else {
        if (YS == YE) {
          //开始等于结束年份
          return _month < MS || _month > ME;
        } else if (year == YS && year < YE) {
          //当前等于开始 小于结束年份
          return _month < MS;
        } else if (year == YE && year > YS) {
          //当前等于结束 大于开始年份
          return _month > ME;
        } else {
          return false;
        }
      }
    },
    _limitYear(year) {
      let [startlimit, endlimit] = this.defaultOptions.limit;
      const [YS, YE, _year] = [
        parseInt(startlimit.slice(0, 4)),
        parseInt(endlimit.slice(0, 4)),
        parseInt(year),
      ];
      return _year < YS || _year > YE;
    },
    //显示的日期
    _renderInputVal() {
      this.dateValue = `${this.currentDate.year}-${
        this.currentDate.month > 9
          ? this.currentDate.month
          : "0" + this.currentDate.month
      }-${
        this.currentDate.day > 9
          ? this.currentDate.day
          : "0" + this.currentDate.day
      }`;
    },
    //初始化
    _initDate() {
      let date = new Date();
      this.currentDate.year = date.getFullYear();
      this.currentDate.month = date.getMonth() + 1;
      this.currentDate.day = date.getDate();
      this._drawDay();
      this._drawYear();
      this._drawMonth();
      this._renderInputVal();
    },
  },
  mounted() {
    this._initDate();
  },
};
</script>
<style lang="scss" scoped>
$mainColor: rgb(123, 180, 255);
* {
  margin: 0;
  padding: 0;
}
@font-face {
  font-family: "iconfont";
  src: url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.eot");
  src: url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.eot?#iefix")
      format("embedded-opentype"),
    url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.woff2") format("woff2"),
    url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.woff") format("woff"),
    url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.ttf") format("truetype"),
    url("//at.alicdn.com/t/font_2504313_rfzffzf8byd.svg#iconfont") format("svg");
}
.iconfont {
  font-family: "iconfont";
  font-size: 24px;
  &:hover {
    opacity: 0.8;
  }
}
.datePicker {
  position: fixed;
  z-index: 99;
  background-color: rgba(1, 1, 1, 0.3);
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  .date_wrapper {
    background-color: #fff;
    border-radius: 6px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font-size: 20px;
    overflow: hidden;
  }
  .date_controller {
    margin: 0;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 20px 20px 10px;
    width: 420px;
    .controller {
      display: flex;
      div {
        margin: 0 3px;
      }
    }
  }
  .date_pick {
    padding: 0 20px 20px 20px;
    width: 420px;
    .list {
      margin: 0;
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;

      .item {
        width: 40px;
        height: 40px;
        line-height: 40px;
        text-align: center;
        padding: 0 10px;
        margin: 10px 0;
      }
    }
  }
  .month_pick,
  .year_pick {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 0 20px 20px 20px;
    width: 420px;
    .item {
      width: 85px;
      height: 40px;
      line-height: 40px;
      text-align: center;
      padding: 0 10px;
      margin: 10px 0;
    }
  }
  .date_active {
    border-radius: 20px;
    background-color: $mainColor;
    color: #fff;
    padding: 6px;
  }
  .date_disabled {
    color: rgb(201, 201, 201);
  }
  .date_limit {
    background-color: rgb(240, 240, 240);
  }
}
</style>